#include "mywidget.h"
#include <QRegExp>
#include <QFrame>
#include <QVBoxLayout>
#include <QHBoxLayout>

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent)
{
    QVBoxLayout* vbox = new QVBoxLayout;
    QHBoxLayout* hbox = new QHBoxLayout;
    p_text_edit = new QTextEdit;
    QFrame* frame = new QFrame;
    p_next = new QPushButton("-");
    QPushButton* b_rst = new QPushButton("n");
    p_le = new MyLineEdit();
    QObject::connect(p_le, SIGNAL(focussed(bool)), this, SLOT(le_focus_changed(bool)));
    hbox->addWidget( p_next);
    QObject::connect(p_next, SIGNAL(pressed()), this, SLOT(process_next()));
    hbox->addWidget( b_rst);
    QObject::connect(b_rst, SIGNAL(pressed()), this, SLOT(process_rst()));
    hbox->addWidget( p_le);
    frame->setLayout( hbox);
    vbox->addWidget( frame);
    vbox->addWidget( p_text_edit);

    setLayout( vbox);

    // internal timer state
    running     = false;
    since_lap   = 0.0;
    total       = 0.0;
    total_lap   = 0.0;
    lap_count   = 0;
    threshold   = MyWidget::DEFAULT_THRESHOLD;
    p_le->setText( QString( "--:-- < %1").arg( to_time( threshold)));

    // timer
    timer = new QTimer( this);
    QObject::connect(timer, SIGNAL(timeout()), this, SLOT(advance_time()));
    timer->start(TIMER_PERIOD_MS);

    stime = new QTime( QTime::currentTime());

    curr_col = MyWidget::LE_WHITE;

    setWindowFlags(Qt::WindowStaysOnTopHint);
}

void MyWidget::set_time_ent( const QString& val)
{
    if ( ! p_le->hasFocus() || running )
    {
        p_le->setText(val);
    }
}

void MyWidget::read_time_ent()
{
    QRegExp re( "[ ]*[\\-\\d]+[ ]*:[ ]*[\\-\\d]+[ ]*<[ ]*(\\d+)[ ]*:[ ]*(\\d+)[ ]*");
    if ( re.indexIn( p_le->text()) != -1 )
    {
        threshold = re.cap( 1).toInt() * 60 + re.cap( 2).toInt();
    }
}

QString MyWidget::to_time( int t4c)
{
    return QString( "%1:%2").arg(t4c/60).arg( t4c%60);
}

QString MyWidget::to_time_w_hours( int t4c)
{
    return QString( "%1:%2:%3").arg(t4c/60/60).arg(t4c/60).arg( t4c%60);
}

void MyWidget::stat_report( const QString& rep_str)
{
    p_text_edit->append( rep_str);
    // TODO adjust view area
}

void MyWidget::process_next()
{
    read_time_ent();

    QTime ltime(QTime::currentTime());
    if ( running )
    {
        // next
        int ctime = stime->secsTo( ltime);
        total_lap += ( ctime - since_lap);
        total     += ( ctime - since_lap);
        since_lap = ctime;
        stat_report( QString( "Lap%1 %2").arg( lap_count)
                     .arg( to_time_w_hours( ( int)total_lap)));
        total_lap = 0.0;
        lap_count += 1;
    } else
    {
        // start
        running = true;
        int ctime = stime->secsTo( ltime);
        since_lap = ctime;
    }
}

void MyWidget::process_rst()
{
    read_time_ent();

    QTime ltime(QTime::currentTime());
    if ( running )
    {
        // stop
        running = false;
        int ctime = stime->secsTo( ltime);
        total_lap += ( ctime - since_lap);
        total     += ( ctime - since_lap);
        since_lap = ctime;
        stat_report( QString( "-Lap%1 %2"). arg(lap_count)
                     .arg( to_time_w_hours( ( int)total_lap)));
        total_lap = 0.0;
        lap_count += 1;
    } else
    {
        // reset
        stat_report( QString( "Race %1\n").arg( to_time_w_hours( (int)total)));
        total = 0.0;
        total_lap = 0.0;
        lap_count = 0;
    }
}

void MyWidget::advance_time()
{
    if ( running )
    {
        // calculate running time
        QTime ltime(QTime::currentTime());
        int run_time = ( int)( stime->secsTo( ltime) - since_lap);
        // update visual controls
        set_time_ent( QString( "%1 < %2").arg(to_time(run_time)).arg(to_time(threshold)));
        p_next->setText("*");
        p_le->setEnabled( false);
        // blinking logic
        int fast_time = ( int)( ( stime->secsTo( ltime) - since_lap) *
                        2 * BLINK_FREQ_BPS);
        if ( run_time > threshold && fast_time % 2 == 0 )
        {
            p_le->setStyleSheet("QLineEdit{background: red;}");
            curr_col = MyWidget::LE_RED;
        }
        else if ( curr_col != MyWidget::LE_WHITE )
        {
            p_le->setStyleSheet("QLineEdit{background: white;}");
            curr_col = MyWidget::LE_WHITE;
        }
        // deiconify logic
        if ( run_time > threshold &&
             ( run_time - threshold ) % BOTHER_PERIOD_S == 0 &&
             ! this->isActiveWindow() )
        {
            showNormal();
            raise();
            activateWindow();
            if ( ! this->isActiveWindow() )
            {
                // this is the only thing I can do
                lower();
                showMinimized();
                showNormal();
                raise();
                activateWindow();
            }
        }
    } else
    {
        //# update visual controls
        if ( total == 0.0 )
        {
            set_time_ent( QString("--:-- < %1").arg( to_time( threshold)));
        }
        else
        {
            set_time_ent( QString("%1 < %2").arg( to_time( (int)total_lap))
                .arg( to_time( threshold)) );
        }
        p_next->setText("-");
        p_le->setEnabled( true);
        if ( curr_col != MyWidget::LE_WHITE )
        {
            p_le->setStyleSheet("QLineEdit{background: white;}");
            curr_col = MyWidget::LE_WHITE;
        }
        // deiconify logic
        if ( ! this->isActiveWindow() )
        {
            showNormal();
            raise();
            activateWindow();
        }
    }

    // schedule periodic update
    timer->start(TIMER_PERIOD_MS);
}

void MyWidget::le_focus_changed( bool is_focused)
{
    if ( is_focused == false )
    {
        read_time_ent();
    }
}
